import React, { forwardRef, useEffect, useRef, useState, useImperativeHandle } from 'react';
import './XSelect.css';
import XTable from "./XTable";
import { XTableColumn, XTableProps } from "@/demos/types";

export interface XSelectProps {
    columns: XTableColumn[];
    dataSource: any[];
    value?: string | number;
    valueField: string;
    displayField: string;
    onChange?: (newValue: any) => void;
    selectedIdx?: number;
    placeholder?: string;
    defaultText?: string;
    onCommit?: (row: any, idx: number, display: string) => void;
}



const XSelect = forwardRef(({
    columns,
    dataSource,
    valueField,
    displayField,
    selectedIdx = -1,
    placeholder,
    onCommit,
    defaultText = '',
    value,
    onChange
}: XSelectProps, ref) => {
    const selectRef = useRef<any>(null);
    const inputRef = useRef<HTMLInputElement>(null);

    // 当组件挂载时，将内部 ref 暴露给父组件
    useImperativeHandle(ref, () => ({
        focus: () => {
            if (inputRef.current) {
                inputRef.current.value = defaultText
                inputRef.current.focus();
                inputRef.current.select();
                setIsOpen(true)
                console.log('datasource', dataSource, defaultText)
                dataSource.map((item, idx) => {
                    if (item[valueField] == value) {
                        console.log('value', value)
                        setCurrentRowIdx(idx)
                        setPreSelectIdx(idx)
                    }
                })
            }
        },
    }));
    const setDefaultValue = ()=>{
        if (value && dataSource) {
            dataSource.map((item, idx) => {
                if (item[valueField] == value) {
                    setCurrentRowIdx(idx)
                    setPreSelectIdx(idx)
                    if (inputRef.current) inputRef.current.value = item[displayField];
                    onChange && onChange(item)
                }
            })
        } else {
            setCurrentRowIdx(-1)
            setPreSelectIdx(-1)
            if (inputRef.current) inputRef.current.value = '';
        }
    }
    useEffect(() => {
        setDefaultValue()
    }, [selectRef, value]);

    const [currentRowIdx, setCurrentRowIdx] = useState(-1);
    const [preSelectIdx, setPreSelectIdx] = useState(-1)
    const dataGridRef = useRef<any>(null);
    const [isOpen, setIsOpen] = useState(false);
    const [selectedValue, setSelectedValue] = useState(value);

    if (selectedIdx > -1) {
        setCurrentRowIdx(selectedIdx)
        setPreSelectIdx(selectedIdx)
    }

    const toggleDropdown = () => {
        if (isOpen) {
            setIsOpen(false);
        } else {
            setIsOpen(true)
            setTimeout(function () {
                dataGridRef.current && dataGridRef.current.setCurrentRowIdx(currentRowIdx)
            }, 100)
        }
    };

    const onInputChange = (event: React.BaseSyntheticEvent) => {
        const newValue = event.target.value
        checkTextSelect(newValue)
    }

    const checkTextSelect = (newValue: string) => {
        console.log('check text select', newValue)
        if (!isOpen) toggleDropdown()
        if (newValue) {
            dataSource.map((row, idx) => {
                if (row && (row[displayField].startsWith(newValue) || row[displayField] === newValue)) {
                    console.log('found one', row, idx)
                    preSelectRow(idx)
                }
            })
        } else {
            setCurrentRowIdx(-1)
            setPreSelectIdx(-1)
            setSelectedValue(undefined)
            dataGridRef.current?.clearSelection()
        }
    }
    const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
        if (event.code == 'ArrowDown' || event.code == 'ArrowUp') {
            if (!isOpen) toggleDropdown()
            //inputRef.current && inputRef.current.blur()
        }
        if (event.code == 'ArrowDown') {
            if (preSelectIdx < dataSource.length) {
                preSelectRow(preSelectIdx + 1)
            }
        }
        if (event.code == 'ArrowUp') {
            if (preSelectIdx > 0) {
                preSelectRow(preSelectIdx - 1)
            }
        }

        if (event.code == 'Enter') {
            if (isOpen) {
                console.log('select on enter', preSelectIdx)
                dataGridRef.current && dataGridRef.current.select(preSelectIdx)
                selectionCommitHandle(dataSource[preSelectIdx], preSelectIdx)
                event.stopPropagation()
                console.log('edit end')
            } else {
                toggleDropdown()
            }
        }
    }

    const preSelectRow = (rowIdx: number) => {
        dataSource.map((_, idx) => {
            if (idx === rowIdx) {
                setPreSelectIdx(idx)
                scrollTo(idx)
                console.log('change background', idx, dataGridRef.current)
                setTimeout(() => dataGridRef.current?.select(idx), 200)

            }
        })
    }

    const scrollTo = (idx: number) => {
        dataGridRef.current?.scrollToIdx(idx)
    }

    const selectionCommitHandle = (row: any, selectedIdx: number) => {
        if (row) {
            if (inputRef.current && row) inputRef.current.value = row[displayField]
            setCurrentRowIdx(selectedIdx)
            setSelectedValue(row[valueField])
            setPreSelectIdx(selectedIdx)
        }
        onChange?.(row[valueField])
        console.log('emit onCommit')
        onCommit?.(row, selectedIdx, row ? row[displayField] : null)
        toggleDropdown()
        
    }

    return (
        <div className="x-select-wrapper" onKeyDown={onInputKeyDown} ref={selectRef}>
            <div className={`custom-select ${isOpen ? 'open' : ''}`} onClick={toggleDropdown}>
                <input ref={inputRef}
                    className="selected-option"
                    type="text"
                    onBlur={(e) => {
                        setTimeout(() => {
                            setIsOpen(false)
                        }, 200)
                    }}
                    onChange={onInputChange}
                    placeholder={placeholder} />
                <div className="dropdown-arrow">&#9662;</div>
            </div>
            {isOpen && (
                <div className="popup">
                    <XTable columns={columns}
                        data={dataSource}
                        ref={dataGridRef}
                        selectMode="row"
                        onSelectChange={selectionCommitHandle}
                    />
                </div>
            )}
        </div>
    );
});

export default XSelect;
